import { useI18n } from 'vue-i18n';
import { message } from '@/components/q-message/message';

/**
 * 当前时间段类别
 */
export function getTimeState(timeNow: Date) {
    const { t } = useI18n();

    // 获取当前小时
    const hours = timeNow.getHours();
    // 设置默认文字
    let state = ``;
    // 判断当前时间段
    if (hours >= 0 && hours <= 10) {
        state = `${t('time.morning')}!`;
    } else if (hours > 10 && hours <= 14) {
        state = `${t('time.midday')}!`;
    } else if (hours > 14 && hours <= 18) {
        state = `${t('time.afternoon')}!`;
    } else if (hours > 18 && hours <= 24) {
        state = `${t('time.evening')}!`;
    }
    return state;
}

/**
 * 处理时间参数的开始和结束
 */
export const getTimeRangeObject = (range: any) => ({
    start: range?.[0] || range?.start || '',
    end: range?.[1] || range?.end || ''
});

/**
 * 处理数字参数变成带单位
 */
export const formatNumber = (number: any): string => {
    let result = '';
    const tenThousand = 10000;
    const million = 1000000;
    const tenMillion = 10000000;
    const hundredMillion = 100000000;

    switch (true) {
        case number >= hundredMillion:
            result = (number / hundredMillion).toFixed(2) + '亿';
            break;
        case number >= tenMillion:
            result = (number / tenMillion).toFixed(2) + '千万';
            break;
        case number >= million:
            result = (number / million).toFixed(2) + '百万';
            break;
        case number >= tenThousand:
            result = (number / tenThousand).toFixed(2) + '万';
            break;
        default:
            result = number.toFixed(0);
            break;
    }

    return result;
};

/**
 * @param {number} 推移时间天数
 * 传入 days 字段推断往前或往后推移的时间
 * 例如：days: 1 从当前时间往后推 1 天， days: -1 从当前时间往前推 1 天
 */
export const calculateDateOffset = (days: number) => {
    const currentDate = new Date(); // 获取当前日期和时间
    const targetDate = new Date(currentDate.getTime() + days * 24 * 60 * 60 * 1000); // 计算目标日期

    return targetDate;
};

/**
 * 判断是否为 document 文档对象
 */
export const canUseDom = () => {
    return !!(typeof window !== 'undefined' && window.document && window.document.createElement);
};

export const canUseDocElement = () => canUseDom() && window.document.documentElement;

/**
 * 获取元素滚轮距离
 */
export const getScroll = (w: Window, top?: boolean): number => {
    let ret = w[`page${top ? 'Y' : 'X'}Offset`];
    const method = `scroll${top ? 'Top' : 'Left'}`;
    if (typeof ret !== 'number') {
        const d: Record<string, any> = w.document;
        ret = d.documentElement[method];
        if (typeof ret !== 'number') {
            ret = d.body[method];
        }
    }
    return ret;
};

/**
 * 元素相对视口的距离
 */
type CompatibleDocument = {
    parentWindow?: Window;
} & Document;
export const offset = (el: Element) => {
    const rect = el.getBoundingClientRect();
    const pos = {
        left: rect.left,
        top: rect.top
    };
    const doc = el.ownerDocument as CompatibleDocument;
    const w = (doc.defaultView || doc.parentWindow) as Window;
    pos.left += getScroll(w);
    pos.top += getScroll(w, true);
    return pos;
};

/**
 * 单位 unit 处理
 */
export const toPx = (unit: string | number) => {
    if (typeof unit === 'string' && unit !== 'auto') {
        return unit.includes('px') ? unit : `${unit}px`;
    } else if (unit === 'auto') {
        return unit;
    } else {
        return `${unit}px`;
    }
};

/**
 * @: 新增搜索参数
 * @param {anyObj} params
 * @param {string} replaceArr
 * @return {*}
 */
export const handleAddKey = (
    params: anyObj,
    replaceArr: string[],
    startSuffix?: string | string[],
    endSuffix?: string | string[]
) => {
    const paramsObj: anyObj = { ...params };
    replaceArr.forEach((item, index) => {
        if (item in paramsObj) {
            let startKey = item + 'Start';
            let endKey = item + 'End';
            if (startSuffix) {
                startKey = Array.isArray(startSuffix) ? startSuffix[index] : startSuffix;
            }
            if (endSuffix) {
                endKey = Array.isArray(endSuffix) ? endSuffix[index] : endSuffix;
            }
            paramsObj[startKey] = paramsObj[item]?.[0] || '';
            paramsObj[endKey] = paramsObj[item]?.[1] || '';
        }
    });

    return paramsObj;
};

/**
 * @: 删除搜索参数
 * @param {anyObj} params
 * @param {string} replaceArr
 * @return {*}
 */
export const handleDelKey = (params: anyObj, keys: string[]) => {
    const paramsObj: any = { ...params };

    keys.forEach(item => {
        if (item in paramsObj) {
            Reflect.deleteProperty(paramsObj, item);
        }
    });

    return paramsObj;
};

/**
 * 通过所传入的 key 获取对应参数
 */
export const transformDataToKeys = <T extends anyObj>(data: T, keys: string[]): T => {
    const result: anyObj = {};
    keys.forEach(key => {
        if (Object.prototype.hasOwnProperty.call(data, key)) {
            result[key] = data[key];
        }
    });
    return result as T;
};

/**
 * @: 处理表单数据
 * @param {SearchConfig} searchConfig
 * @return {*}
 */
export const handleFormData = (searchConfig: PageConfig) => {
    const params: anyObj = {};
    const date: anyObj = {};
    searchConfig.items.forEach(item => {
        const { modelKey, itemType, default: def, dateRange } = item;
        if (def !== undefined) {
            params[modelKey!] = def;
        } else {
            params[modelKey!] = itemType === 'number' ? 0 : '';
        }
        if (dateRange) {
            date[modelKey!] = dateRange;
        }
    });
    return { params, date };
};

/**
 * @: 把表单的label加上：并统一：格式
 * @param {string} label
 * @return {*}
 */
export const handleLabel = (label: string | undefined) => {
    const semicolon = ':';

    if (!label) return '';
    const lastChar = label.charAt(label.length - 1);
    if (lastChar === semicolon) return label;
    if (lastChar === ':') {
        return label.slice(0, -1) + semicolon;
    }
    return label + semicolon;
};

/**
 * 通过 id 检索当前所处列表索引位置
 */
export const getColumnIndex = (config: any[], id: string) => {
    return config.findIndex((config: any) => config.validProps?.id === id);
};

/**
 * @: 对传入的数据添加children
 * @param {any} payload 源数据
 * @param {string} key 子父值相同的字段 用来做成children
 * @param {object} reset 要重置的字段
 * @return {*}
 */
export const handleChildren = (
    payload: any[],
    key: string,
    reset: { [key: string]: string } = {}
) => {
    const onlyObj = handleClassify(payload, key);
    return addChildren(onlyObj, reset);
};

// 通过传入的key值对数组进项分类
const handleClassify = (payload: any[], key: string) => {
    const obj: { [key: string]: any[] } = {};
    payload.forEach(item => {
        if (obj[item[key]]) {
            obj[item[key]].push(item);
        } else {
            obj[item[key]] = [item];
        }
    });
    return obj;
};

// 对传入的对象进行子父级划分并吧传入的字段置空
const addChildren = (onlyObj: { [key: string]: any[] }, reset: { [key: string]: string }) => {
    const result: any[] = [];
    Object.keys(onlyObj).forEach((item, index) => {
        const children = onlyObj[item].slice(1).map(item => {
            return {
                ...item,
                ...reset
            };
        });

        const parent = onlyObj[item][0];
        parent.children = children;

        result[index] = parent;
    });
    return result;
};

/**
 * 字符串按特定符号切割为数组对象
 */
export const splitToMark = (str: string, mark: string = ',') => {
    if (!str) return;
    return str.split(mark);
};

/**
 * 通过特定 key 过滤对应数据列表
 * @param {Boolean} isDeep 是否递归过滤
 */
export const filterArrToKey = <T extends anyObj>(
    arr: T[],
    key: string,
    isDeep: boolean = false
): T[] => {
    if (!arr) return [];
    return arr.map(item => {
        // 判断是否需要递归处理
        if (isDeep && item.children) {
            return filterArrToKey(item.children, key, isDeep);
        }
        return item[key];
    });
};

/**
 * 抹平多层数组层级
 */
export const flatArr = <T = any>(arr: T[]) => {
    return arr.flat();
};

/**
 * 判断是否为数组
 */
export const isArray = (arr: unknown) => Array.isArray(arr);

/**
 * 判断是否为函数
 */
export const isFunction = (fn: unknown) => fn instanceof Function;

/**
 * 过滤 select 选择项
 */
export const filterOption = (selectArr: any, val: string | number) => {
    const obj = selectArr.find((ite: any) => ite.value === val);
    if (obj) {
        return obj.label;
    }
    return '--';
};

/**
 * 转换函数为标准 select 字段值 => { value: any, label: any, children: [] }
 */
export const transformArray = <T extends anyObj>(arr: T[], i: number) => {
    return arr.map(item => {
        const { id, title, menuChildren } = item;
        const transformedItem: TransformedItem = {
            value: id,
            label: title
        };

        if (i != null) transformedItem['level'] = i;
        if (menuChildren && menuChildren.length > 0) {
            transformedItem.children = transformArray(menuChildren, ++i);
        }
        return transformedItem;
    });
};

/**
 * 通过传入指定 key 递归检索出满足添加的数据
 */
export const filterByKey = (
    arr: any[],
    key: number | string,
    attr: string = 'id'
): anyObj | null => {
    if (key == null) return key;
    for (let i = 0; i < arr.length; i++) {
        if (arr[i][attr].toString().trim() === key.toString()) {
            return arr[i];
        }
        if (arr[i].children) {
            const result = filterByKey(arr[i].children, key, attr);
            if (result) {
                return result;
            }
        }
    }
    return null;
};

/**
 * 递归删除当前数据
 */
export const removeDataById = (data: any[], id: number | string) => {
    for (let i = 0; i < data.length; i++) {
        if (data[i].id === id) {
            data.splice(i, 1);
            break;
        }
        if (data[i].children && data[i].children.length > 0) {
            removeDataById(data[i].children, id);
        }
    }
};

/**
 * 对数组树 key 值做转换，如将
 * [ id: 1, menuChildren: [{ id: 2, menuChildren: [] }] ] 转换成 [ id: 1, children: [{ id: 2, children: [] }] ]
 */
export const replaceKeyWithChildren = (arr: any[], key: string = 'menuChildren') => {
    return arr.map(item => {
        if (item[key] && Array.isArray(item[key])) {
            item.children = replaceKeyWithChildren(item[key]);
            delete item[key];
        }
        return item;
    });
};

/**
 * 判断当前 key 是否存在数组中
 */
export const isExistArrKey = (arr: Array<string | number>, key: string | number) => {
    return arr.includes(key);
};

/**
 * 通过传入匹配 ids 列表从列表数据中获取列表中存在的 id 列表
 * @param {anyObj[]} arr1 列表数据
 * @param {Array<string | number>} arr2 匹配 ids
 */
export const getArrIdListToIds = (
    arr1: anyObj[],
    arr2: Array<string | number>
): Array<string | number> => {
    return arr1.filter((item: any) => arr2.includes(item.id)).map((item: any) => item.id);
};

/**
 * 将数组转换成字符串
 * @param {any[]} arr 转换数组
 * @param {string} key 转换 key
 * @param {string} joinStr 拼接符号
 * @retrun joinStr 拼接的字符串
 */
export const convertArrToStr = <T extends anyObj>(arr: T[], key: string, joinStr?: string) => {
    if (arr == null) return '';
    const equipmentNumbers = arr.map(obj => obj[key]);
    const result = equipmentNumbers.join(joinStr || ',');

    return result;
};

/**
 * 将树结构 以 children 字段拍平
 */
type FlattenArray = { children: any };
export const flattenArray = <T extends FlattenArray = any>(arr: T[]) => {
    let newArr: T[] = [];
    arr.forEach(function (obj) {
        newArr.push({
            ...obj
        });
        if (obj.children) {
            newArr = newArr.concat(flattenArray(obj.children));
        }
    });
    return newArr;
};

/**
 * 计算结构树数组中包含 children 字段的数组总长度
 * @return {*}
 */
export const calculateTreeLen = <T extends { children?: T[] }>(arr: T[]): number => {
    try {
        if (!Array.isArray(arr)) throw new Error('arr 不是数组类型');
        let totalNum = 0;
        totalNum += arr.length;
        for (const obj of arr) {
            if (obj.children) {
                totalNum += calculateTreeLen(obj.children) as number;
            }
        }
        return totalNum;
    } catch (e) {
        console.log(e);
        return 0;
    }
};

/**
 * 获取数组中的最大值
 */
export const getMax = (arr: number[]) => Math.max(...arr);

/**
 * @: 判断是否有重复的值 重复返回true
 * @param {anyObj} arr
 * @param {string} key
 * @return {*}
 */
export const checkRepeat = (arr: anyObj[], key: string[]) => {
    const values: anyObj = {};
    for (let i = 0; i < arr.length; i++) {
        for (let j = 0; j < key.length; j++) {
            const value = arr[i][key[j]];
            if (values[value]) {
                const { name, line } = values[value];
                return {
                    line: [line, i + 1],
                    name,
                    value
                };
            }
            values[value] = {
                name: key[j],
                line: i + 1
            };
        }
    }
    return false;
};

export const RepeatMsg = (msg: { line: number[]; label: string; value: string }) => {
    const { line, label, value } = msg;

    message.error(`第${line[0]}行、第${line[1]}行：${label}【${value}】重复`);
};

/**
 * 转换 null or undefined 值
 */
export const transformValue = (value: any) => {
    value = isArray(value) ? value.join(',') : value; // 默认数组用逗号拼接
    return value ?? '--';
};

/**
 * @: 根据传入的字符串生成颜色
 * @param {*} new
 * @param {*} string
 * @return {*}
 */
const mapColor = new Map<string, string>();
export const generateLightColor = (str: string = '暂无数据', transparent = '33') => {
    let color = mapColor.get(str);
    if (color) return color;

    // 使用传入的字符串生成哈希值
    let hashValue = str.split('').reduce((acc, char) => {
        acc = (acc << 5) - acc + char.charCodeAt(0);
        return acc & acc;
    }, 0);

    // 将哈希值转换为正整数
    hashValue = Math.abs(hashValue) * 1234566789;

    // 生成RGB颜色值
    const red = Math.abs(hashValue % 256)
        .toString(16)
        .padStart(2, '0');
    const green = Math.abs((hashValue >> 8) % 256)
        .toString(16)
        .padStart(2, '0');
    const blue = Math.abs((hashValue >> 16) % 256)
        .toString(16)
        .padStart(2, '0');

    // 生成16进制颜色代码
    color = `#${red}${green}${blue}${transparent}`;
    mapColor.set(str, color);

    return color;
};

/**
 * 获取 cursor 手势图标
 */
export const getCursorIcon = (icon: string, left: number = 8, top: number = 8) => {
    return `url(${icon}) ${left} ${top}, default`;
};

/**
 * @: 把ref数据归为普通数据
 */
export const deepUnRef = (val: any): any => toRaw(toValue(val)); // 有可能是reactive 对象

/**
 * @: 深克隆ref对象返回值是非ref对象
 */
export const deepClone = (obj: any, cache?: Map<any, any>) => {
    if (!cache) {
        cache = new Map();
    }
    const source = deepUnRef(obj);
    if (source instanceof Object) {
        if (cache.get(source)) {
            return cache.get(source);
        }
        let result: any;
        if (source instanceof Array) {
            result = [];
        } else {
            result = {};
        }
        cache.set(source, result);
        for (const key in source) {
            result[key] = deepClone(deepUnRef(source[key]), cache);
        }
        return result;
    } else {
        return source;
    }
};

/**
 * 获取当前时间
 */
export const getTime = () => new Date().getTime();

/**
 * @description 字符串小于 10 补全
 * @param {string|number} str 需要补全的数据
 */
export const completionNumber = (str: string | number) => str.toString().padStart(2, '0');
